package com.example.myapplication.service;

import android.annotation.SuppressLint;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.Service;
import android.content.Intent;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioTrack;
import android.os.Binder;
import android.os.Build;
import android.os.IBinder;
import android.util.Log;

import androidx.annotation.Nullable;

import com.example.myapplication.R;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Arrays;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class AudioService extends Service {

    private static final String TAG = AudioService.class.getName();

    private final MyBinder myBinder = new MyBinder();

    private AudioTrack audioTrack;
    private int sampleRate = 8000;
    private boolean isStereo = false;
    private int bufferSize;

    private boolean isPlaying = false;

    private ExecutorService executorService;

    private final String channelId = "jtt1078";

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        buildNotificationChannel();
        startForeGround();
        return myBinder;
    }

    public class MyBinder extends Binder {
        public AudioService getService(){
            return AudioService.this;
        }
    }

    @Override
    public void onCreate() {
        super.onCreate();
        audioTrack = new AudioTrack(
                AudioManager.STREAM_MUSIC,
                sampleRate,
                isStereo ? AudioFormat.CHANNEL_OUT_STEREO : AudioFormat.CHANNEL_OUT_MONO,
                AudioFormat.ENCODING_PCM_16BIT,
                getAudioTrackMinBufferSize(),
                AudioTrack.MODE_STREAM
                );
    }

    @Override
    public void onDestroy() {
        if(audioTrack != null){
            audioTrack.stop();
            audioTrack.release();
        }
        super.onDestroy();
    }

    public void stopPlay(){
        executorService.shutdownNow();
        if(isPlaying){
            isPlaying = false;
            audioTrack.stop();
        }
    }

    public void onAudioData(byte[] data){
        if(!isPlaying){
            isPlaying = true;
            audioTrack.play();
            executorService = Executors.newSingleThreadExecutor();
        }
        try{
            if(!executorService.isShutdown()){
                executorService.execute(()->{
                    int offset = 0;
                    int len = data.length;
//            Log.d(TAG, "data len "+len);
                    while (offset < len){
                        int size = bufferSize;
                        size = offset + size > len ? len - offset : size;
//                Log.d(TAG, "offset "+offset+" size "+size);
                        audioTrack.write(data, offset, size);
                        offset += size;
                    }
                });
            }

        }catch (Exception e){
            e.printStackTrace();
        }



    }

    private int getAudioTrackMinBufferSize(){
        bufferSize = AudioTrack.getMinBufferSize(
                sampleRate,
                isStereo ? AudioFormat.CHANNEL_OUT_STEREO : AudioFormat.CHANNEL_OUT_MONO,
                AudioFormat.ENCODING_PCM_16BIT
        );
        Log.d(TAG, "audioTrack bufferSize "+bufferSize);
        return bufferSize;
    }

    void buildNotificationChannel(){
        NotificationManager manager;
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
            NotificationChannel channel = new NotificationChannel(channelId, channelId, NotificationManager.IMPORTANCE_LOW);
            channel.setDescription(
                    "notification_channel_description"
            );
            manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
            Log.d(TAG,"hasIt ? "+ manager.getNotificationChannel(channelId));
            if(manager.getNotificationChannel(channelId) == null){
                manager.createNotificationChannel(channel);
            }
        }
    }

    @SuppressLint("ForegroundServiceType")
    void startForeGround(){
        Notification.Builder builder;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            builder = new Notification.Builder(this, channelId);
        }else{
            builder = new Notification.Builder(this);
        }
        builder.setSmallIcon(R.mipmap.ic_launcher);
        builder.setContentText("jtt1078");
        int NOTIFICATION_ID = 0x99;
        startForeground(NOTIFICATION_ID, builder.build());

    }
}
